package nl.tudelft.jpacman.npc.ghost;

import com.google.common.collect.Lists;
import nl.tudelft.jpacman.board.*;
import nl.tudelft.jpacman.level.*;
import nl.tudelft.jpacman.points.PointCalculator;
import nl.tudelft.jpacman.sprite.PacManSprites;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ClydeTest {
    private GhostMapParser parser;
    private Level l;
    private Player player;
    private Direction d;

    @BeforeAll
    void setUp() {
        PacManSprites sprites = new PacManSprites();
        GhostFactory ghostFactory = new GhostFactory(sprites);
        BoardFactory boardFactory = new BoardFactory(sprites);
        LevelFactory levelFactory = new LevelFactory(
            sprites,
            ghostFactory,
            mock(PointCalculator.class));
        player = new PlayerFactory(sprites).createPacMan();
        parser = new GhostMapParser(levelFactory, boardFactory, ghostFactory);

        String[] map = {
            "############",
            "#P        C#",
            "############"
        };
        l = parser.parseMap(Lists.newArrayList(map));
        d = Direction.valueOf("NORTH");
        player.setDirection(d);
        l.registerPlayer(player);
    }

    void reParser(String[] map) {
        l = parser.parseMap(Lists.newArrayList(map));
        d = Direction.valueOf("NORTH");
        player.setDirection(d);
        l.registerPlayer(player);
    }

    @Test
    public void test() {
        Clyde clyde = Navigation.findUnitInBoard(Clyde.class, l.getBoard());
        System.out.println(clyde);
    }

    /**
     * 间隔等于8
     */
    @Test
    public void equalTest() {
        String[] map = {
            "############",
            "#       P  #",
            "#C##########"
        };
        reParser(map);
        Clyde clyde = Navigation.findUnitInBoard(Clyde.class, l.getBoard());
        Optional<Direction> direction = clyde.nextAiMove();
        assert direction.isPresent() && direction.get().equals(Direction.SOUTH);
    }

    /**
     * 间隔小于8
     */
    @Test
    public void lessTest() {
        String[] map = {
            "############",
            "#      PC  #",
            "############"
        };
        reParser(map);
        Clyde clyde = Navigation.findUnitInBoard(Clyde.class, l.getBoard());
        Optional<Direction> direction = clyde.nextAiMove();
        assert direction.isPresent() && direction.get().equals(Direction.EAST);
    }

    /**
     * 间隔大于8
     */
    @Test
    public void moreTest(){
        String[] map = {
            "###################",
            "#  P           C  #",
            "###################"
        };
        reParser(map);
        Clyde clyde = Navigation.findUnitInBoard(Clyde.class, l.getBoard());
        Optional<Direction> direction = clyde.nextAiMove();
        assert direction.isPresent() && direction.get().equals(Direction.WEST);
    }

}
